﻿#include "bb_api.h"
#include "debug_rpc.h"
#include "getopt.h"
#include <cstdlib>
#include <stdio.h>
#include <string.h>

typedef struct {
    char ip[128];
    int  port;
    int  spmacflg;
    char mac[128];
    int  workflg;
} cmddbg_info;

void dbg_recv_fun(struct dbg_hdl* hdl, void* priv, unsigned char* buff, int len)
{
    cmddbg_info* pinfo = (cmddbg_info*)priv;
    if (len > 0) {
        buff[len] = 0;
        printf("%s", (char*)buff);
    }
}

void bb_event_offline(void* arg, void* usr)
{
    cmddbg_info* pinfo = (cmddbg_info*)usr;
    printf("dev offline cb\n");
    pinfo->workflg = 0;
}

static int set_cb(bb_dev_handle_t* pdh, int evt, bb_event_callback pcb, void* priv)
{
    bb_set_event_callback_t cb;
    cb.callback = pcb;
    cb.event    = (bb_event_e)evt;
    cb.user     = priv;

    int ret = bb_ioctl(pdh, BB_SET_EVENT_SUBSCRIBE, &cb, 0);

    if (ret) {
        printf("set callback err!\n");
        return -1;
    }
    printf("set evt %d callback ok!\n", evt);

    return 0;
}

void print_help(void) { }

int main(int argc, char* argv[])
{
    cmddbg_info info;
    info.workflg  = 1;
    info.port     = BB_PORT_DEFAULT;
    info.spmacflg = 0;
    strcpy(info.ip, "127.0.0.1");

    int listflg = 0;

    int c = 0;
    while (1) {
        int                  option_index   = 0;
        static struct option long_options[] = {
            {"help",  no_argument,       0, 'h'},
            { "ip",   required_argument, 0, 'i'},
            { "port", required_argument, 0, 'p'},
            { "mac",  required_argument, 0, 'm'},
            { "list", no_argument,       0, 'l'},
            { 0,      0,                 0, 0  },
        };

        c = getopt_long(argc, argv, "i:p:m:hl", long_options, &option_index);
        if (c == -1) {
            break;
        }

        switch (c) {
        case 'p':
            info.port = (int)strtoul(optarg, NULL, 10);
            break;
        case 'i':
            strcpy(info.ip, optarg);
            break;
        case 'm':
            info.spmacflg = 1;
            strcpy(info.mac, optarg);
            break;
        case 'l':
            listflg = 1;
            break;
        case 'h':
            print_help();
            exit(0);
            break;
        default:
            break;
        }
    }

    bb_host_t* phost;

    int ret = bb_host_connect(&phost, info.ip, info.port);

    if (ret) {
        printf("connect failed = %d\n", ret);
        exit(-1);
    }

    bb_dev_t** devs;

    int sz = bb_dev_getlist(phost, &devs);
    if (sz <= 0) {
        printf("dev cnt = 0\n");
        exit(-1);
    }

    bb_dev_handle_t* hbb = NULL;

    if (listflg) {
        for (int i = 0; i < sz; i++) {
            bb_dev_info_t dev_info;
            bb_dev_getinfo(devs[i], &dev_info);
            printf("dev %d mac :%s\n", i, (char*)dev_info.mac);
        }
        return 0;
    }

    if (info.spmacflg) {
        for (int i = 0; i < sz; i++) {
            bb_dev_info_t dev_info;
            bb_dev_getinfo(devs[i], &dev_info);
            if (!strcmp((char*)dev_info.mac, info.mac)) {
                hbb = bb_dev_open(devs[i]);
                break;
            }
        }
        if (!hbb) {
            printf("mac %s not found\n", info.mac);
            return -1;
        }
    } else {
        hbb = bb_dev_open(devs[0]);
    }

    if (!hbb) {
        printf("dev probe err\n");
        return -1;
    }

    set_cb(hbb, BB_EVENT_OFFLINE, bb_event_offline, &info);

    struct dbg_hdl* dbg = debug_setup(hbb, dbg_recv_fun, &info);
    if (dbg) {
        while (1) {
            char  buff[1024];
            char* out = fgets(buff, 1024, stdin);

            if (!out) {
                printf("get NULL output!!\n");
            }

            int len = strlen(buff);

            if (!info.workflg) {
                break;
            }
            dbg_write(dbg, (unsigned char*)buff, len);
        }
    }

    bb_dev_close(hbb);

    bb_dev_freelist(devs);

    bb_host_disconnect(phost);

    return 0;
}
